uniform sampler2D leftFrontTopTexture; 
uniform sampler2D rightBackBottomTexture; 
uniform sampler2D depthTexture;
uniform vec2 screenSize;
uniform bool useSmoothstep;
uniform float smoothstepStart, smoothstepEnd;
uniform vec4 color;
uniform int gaussian;

           
void main(void) { 

  vec2 depthOffsets[16];  

	
  depthOffsets[0]=   vec2(-2.0, -1.0);
  depthOffsets[1]=   vec2(-2.0,  0.0);
  depthOffsets[2]=   vec2(-2.0,  1.0);	
  depthOffsets[3]=   vec2(-1.0, -2.0);
  depthOffsets[4]=   vec2(-1.0,  2.0);	
  depthOffsets[5]=  vec2( 0.0, -2.0);
  depthOffsets[6]=  vec2( 0.0,  2.0);
  depthOffsets[7]=  vec2( 1.0, -2.0);
  depthOffsets[8]=  vec2( 1.0,  2.0);		
  depthOffsets[9]=  vec2( 2.0, -1.0);
  depthOffsets[10]=  vec2( 2.0,  0.0);
  depthOffsets[11]=  vec2( 2.0,  1.0);
  depthOffsets[12]=  vec2( 2.0, -2.0);	
  depthOffsets[13]=  vec2( 2.0, -2.0);	
  depthOffsets[14]=   vec2(-2.0, -2.0);	
  depthOffsets[15]=   vec2(-2.0,  2.0);

  vec2 offsets[9];

  offsets[0]=  vec2(-1.0, -1.0);
  offsets[1]=  vec2( 0.0, -1.0);
  offsets[2]=  vec2( 1.0, -1.0);
  offsets[3]=  vec2(-1.0,  0.0);
  offsets[4]=  vec2( 0.0,  0.0);
  offsets[5]=  vec2( 1.0,  0.0);
  offsets[6]=  vec2(-1.0,  1.0);
  offsets[7]=  vec2( 0.0,  1.0);
  offsets[8]=  vec2( 1.0,  1.0); 

  float result; 
  float depth[9]; 
  float minDepth= 1.0;
  vec3 leftFrontTop[9];
  vec3 rightBackBottom[9];	
  int i; 
  float dx,dy; 
  vec3 nx,ny;

  float centerDepth= texture2D(depthTexture, gl_FragCoord.xy/screenSize).x;

  for(i=0;i<9;i++){ 
  
    depth[i] = texture2D(depthTexture, (gl_FragCoord.xy+offsets[i])/screenSize).r; 
    if(depth[i]<minDepth) minDepth= depth[i];
    leftFrontTop[i] = texture2D(leftFrontTopTexture, (gl_FragCoord.xy+offsets[i])/screenSize).rgb;
    rightBackBottom[i] = texture2D(rightBackBottomTexture, (gl_FragCoord.xy+offsets[i])/screenSize).rgb;
  }
                   
  dx=  depth[0]+2.0*depth[1]+depth[2]-depth[6]-2.0*depth[7]-depth[8]; 
  dy=  depth[0]-depth[2]+2.0*depth[3]-2.0*depth[5]+depth[6]-depth[8]; 

  result = 3.0*sqrt(dx*dx+dy*dy); 

             
  nx= leftFrontTop[0]+2.0*leftFrontTop[1]+leftFrontTop[2]-leftFrontTop[6]-2.0*leftFrontTop[7]-leftFrontTop[8]; 
  ny= leftFrontTop[0]-leftFrontTop[2]+2.0*leftFrontTop[3]-2.0*leftFrontTop[5]+leftFrontTop[6]-leftFrontTop[8]; 

  result += length(sqrt(nx*nx+ny*ny));

  nx= rightBackBottom[0]+2.0*rightBackBottom[1]+rightBackBottom[2]-rightBackBottom[6]-2.0*rightBackBottom[7]-rightBackBottom[8]; 
  ny= rightBackBottom[0]-rightBackBottom[2]+2.0*rightBackBottom[3]-2.0*rightBackBottom[5]+rightBackBottom[6]-rightBackBottom[8]; 

  result += length(sqrt(nx*nx+ny*ny));

  result/= 5.0;
  if(useSmoothstep){
    result= smoothstep(smoothstepStart, smoothstepEnd, result);
  }	
  if(result!=0.0){
    gl_FragColor= vec4(color.xyz, result);
    if(centerDepth==1.0){
      if(minDepth==1.0){
        float depth= 1.0;
	if(gaussian==3){
          for(i=0;i<12;i++){ 
            depth = texture2D(depthTexture, (gl_FragCoord.xy+depthOffsets[i])/screenSize).r; 
            if(depth<minDepth) minDepth= depth;
          }
	}
	else if(gaussian==5){
          for(i=0;i<16;i++){ 
            depth = texture2D(depthTexture, (gl_FragCoord.xy+depthOffsets[i])/screenSize).r; 
            if(depth<minDepth) minDepth= depth;
          }
	}
      }
      gl_FragDepth= minDepth;	
    }
    else gl_FragDepth= gl_FragCoord.z;
  }  
  else{
    discard;
  }

  //gl_FragColor= vec4(texture2D(depthTexture, (gl_FragCoord.xy)/screenSize).xyz, 1.0);
}
